package w83a.Thread;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import n38a.exe.N38APISesion;

import org.w3c.dom.Document;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import w83a.iLote4.stubs.W83aNSHFFacadeWS;
import w83a.w83aBeans.W83AUsuarioBean;
import w83a.w83aBeans.W83aNotificacionesBean;
import w83a.w83aDAO.W83ANotificacionesDAO;
import w83a.w83aManager.W83AEjGvDocumento;
import w83a.w83aManager.W83AWebServiceutils;
import w83a.w83aUtilidadesComunes.W83ABase64;
import w83a.w83aUtilidadesComunes.W83AInformacionProcedimiento;
import w83a.w83aUtilidadesComunes.W83AProperties;
import w83a.w83aUtilidadesComunes.W83ASolicitudPreaviso;
import w83a.w83aUtilidadesComunes.W83aClsConstantes;
import w83a.w83aUtilidadesComunes.W83aClsTrazas;

import com.ejie.y31.factory.Y31JanoServiceAbstractFactory;
import com.ejie.y31.service.Y31JanoService;
import com.ejie.y31.vo.Y31AttachmentBean;



public class W83ANotificacionThread extends Thread {
	ArrayList listaSindicatos;
	W83AInformacionProcedimiento info;
	W83AUsuarioBean sindicato;
	W83aNotificacionesBean infoNotificacion;
	W83ASolicitudPreaviso preaviso;
	String direccionEnvio;
	String nombreFichero;
	String documentoImportadoOriginal;
	String idioma;



// Constructor para almacenar nuestro nombre
public W83ANotificacionThread( ArrayList listaSindicatos, W83AInformacionProcedimiento info, W83ASolicitudPreaviso preaviso,W83aNotificacionesBean infoNotificacion,String direccionEnvio,  String nombreFichero, String documentoImportadoOriginal, String idioma) {
	this.listaSindicatos=listaSindicatos;
	this.info=info;
	this.preaviso=preaviso;
	this.infoNotificacion=infoNotificacion;
	this.direccionEnvio=direccionEnvio;
	this.nombreFichero=nombreFichero;
	this.documentoImportadoOriginal=documentoImportadoOriginal;
	this.idioma=idioma;;
    }



public static String getTokenXLNets (String idAplic){
  String token = null;
 
  try {
    N38APISesion miAPISesion = new N38APISesion();
    Document miSesion;
    miSesion=miAPISesion.n38APISesionCrearApp(idAplic);
    token = DOM2String(miSesion);

  } catch (Exception e){
	  W83aClsTrazas.trazaDebug(null, "P16BPlateaUtils->getTokenXLNets: Excepcion creando el token de aplicacion");
	  e.printStackTrace();
  }
 
  return token;
}

/**
 * Lee un fichero y devuelve el contenido
 * @param elFichero el nombre del fichero
 * @param codificar indica si ha de codificarse el contenido 
 * @return el contenido
 */
public static String leerFichero(String elFichero, boolean codificar){
	String cadenaSesion= "";
	try {
		File laSesion= new File(elFichero);
		
		InputStream is = new FileInputStream(laSesion);
	    
        long length = laSesion.length();
	    
        // Create the byte array to hold the data
        byte[] bytes = new byte[(int) length];
	    
	    // Read in the bytes
	    int offset = 0;
	    int numRead = 0;
	    while (offset < bytes.length
	    		&& (numRead=is.read(bytes, offset, bytes.length - offset)) >= 0) {
	    	offset += numRead;
        }

        // Ensure all the bytes have been read in
        if (offset < bytes.length) {
            throw new IOException("No se ha podido leer " + elFichero);
        }

        // Close the input stream and return bytes
        is.close();

        BASE64Encoder encoder = new BASE64Encoder();

        if (codificar) {
            cadenaSesion = encoder.encode(bytes);
        } else {
            cadenaSesion = new String(bytes);
        }

	} catch (Exception e) {
		W83aClsTrazas.trazaDebug(null, "P16BPlateaUtils.leerFichero->EXCEPTION");
	}

	return cadenaSesion;
}


public static String DOM2String(Document doc)
{
	TransformerFactory transformerFactory =TransformerFactory.newInstance();
	Transformer transformer = null;
	try{
		transformer = transformerFactory.newTransformer();
	}catch (javax.xml.transform.TransformerConfigurationException error){
		//int coderror=123;
		//String msgerror=error.getMessage();
		return null;
	}
	 
	Source source = new DOMSource(doc);
	 
	StringWriter writer = new StringWriter();
	Result result = new StreamResult(writer);
	try{
		transformer.transform(source,result);
	}catch (javax.xml.transform.TransformerException error){
		//int coderror=123;
		//String msgerror=error.getMessage();
		return null;
	}
	 
	String s = writer.toString();
	return s;//NOPMD
}


// El metodo run() es similar al main(), pero para
// threads. Cuando run() termina el thread muere
public void run() {

	try {
		W83aClsTrazas.trazaDebug(null," ---- EMPIEZA EL THREAD ----");
		
		//Recuperamos el token de aplicación de xlnets
        N38APISesion miAPISesion = new N38APISesion();
        Document miSesion=miAPISesion.n38APISesionCrearApp("w83a");
        infoNotificacion.setSessionTokenXLNET(DOM2String(miSesion));
        
    	W83aClsTrazas.trazaDebug(null," ---- coge el token: " + miSesion);
    	
    	
    	String firma="";
    	boolean error=false;
        for(int i=0;i<listaSindicatos.size();i++){
        	
        
    		String rutaDoc = "/r02g/w83a/"+nombreFichero;
    		W83aClsTrazas.trazaDebug(null,"rutaDoc:"+rutaDoc);
    		
    		 //PIF
        	InputStream is = new ByteArrayInputStream(documentoImportadoOriginal.getBytes());
        	W83aClsTrazas.trazaDebug(null,"documentoImportadoOriginal: "+documentoImportadoOriginal);
        	W83aClsTrazas.trazaDebug(null,"is:"+is );
        	
        	Y31JanoService service = Y31JanoServiceAbstractFactory.getInstance();
        	W83aClsTrazas.trazaDebug(null,"despues del service");
        	
        	Y31AttachmentBean rdo = service.put(miSesion, is, rutaDoc, false, new Long (3600));
        	W83aClsTrazas.trazaDebug(null,"despues del put");
        	
        	String rutaFichero = rdo.getFilePath();
        	W83aClsTrazas.trazaDebug(null,"rutaFichero: "+rutaFichero );
    	

        	
        	sindicato = (W83AUsuarioBean) listaSindicatos.get(i);
        	W83aClsTrazas.trazaDebug(null,"sindicato "+sindicato.getDniUsuario());
        	
//**********************************INICIO GENERAR NOTIFICACION********************************************//
        	//Creamos el notificación Task
        	String notificationCreateTask = W83AWebServiceutils.generarNotificationCreateTask(info.getProcedureId(), info, infoNotificacion, sindicato ,preaviso,direccionEnvio, rutaFichero, idioma);
        	W83aClsTrazas.trazaDebug(null,"Se ha obtenido el Notificacion Task");
        	
        	//Llamada a WS para crear la notificación
        	String resultadoNotificacion = W83AEjGvDocumento.generarNotificacion(infoNotificacion.getSessionTokenXLNET(), notificationCreateTask);
        	W83aClsTrazas.trazaDebug(null," resultadoNotificacion ---->" +resultadoNotificacion);
        	
        	//Pasamos a base64 la notificación
        	String result = W83ABase64.decodeToString(resultadoNotificacion);
        	W83aClsTrazas.trazaDebug(null,"Resultado generar notificacion decodificado---->" +result);
//**********************************FIN GENERAR NOTIFICACION********************************************//
        	
        	

//**********************************INICIO FIRMAR NOTIFICACION****************************************************************//
        	if("".equals(result)){
        		W83aClsTrazas.trazaDebug(null,"Resultado generar notificacion vacio ERROR");
        		//Si esta vacía la notificación error
        		error=true;
        	}else{
	        	//String documento=W83AStringUtil.obtenerPatron(result, W83aClsConstantes.ETIQUETADOCUMENTO);
	        	//String textoafirmar=W83AStringUtil.obtenerPatron(result, W83aClsConstantes.ETIQUETATEXTOAFIRMAR);
	        	//W83aClsTrazas.trazaDebug(null,"Texto plano a firmar"+textoafirmar);
//				if((null==documento || documento.equals("")) && (null==textoafirmar || textoafirmar.equals(""))){
//					//Si el documento viene vacío ERROR
//					W83aClsTrazas.trazaDebug(null,"documento viene vacío ERROR");
//					error=true;
//				}else{
					//firmar notificacion.
					W83aClsTrazas.trazaDebug(null,"Intentando Obtener la firma simple para la notificación");
					
					//Recuperamos la certificación para firmar la notificación
					String certificateId= "";
					if(infoNotificacion.getTerritorioUsuarioXLNET().equals(W83aClsConstantes.CONSTANTE_BIZKAIA)){
						certificateId= W83AProperties.getProperty("w83a", "certificateId.bizkaia");
					}else if(infoNotificacion.getTerritorioUsuarioXLNET().equals(W83aClsConstantes.CONSTANTE_GIPUZKOA)){
						certificateId= W83AProperties.getProperty("w83a", "certificateId.gipuzkoa");
					}else if(infoNotificacion.getTerritorioUsuarioXLNET().equals(W83aClsConstantes.CONSTANTE_ALAVA)){
						certificateId= W83AProperties.getProperty("w83a", "certificateId.araba");
					}else{
						certificateId= W83AProperties.getProperty("w83a", "certificateId.general");
					}
					W83aClsTrazas.trazaDebug(null,"firmar notificacion. Territorio usuario: "+infoNotificacion.getTerritorioUsuarioXLNET());
					W83aClsTrazas.trazaDebug(null,"Certificado ---->" +certificateId);
					
					
					
					//Pasamos a base64 la notificación para firmarla
					
					BASE64Decoder decoder = new BASE64Decoder();

					String ejgvNotificacionB64preparado = new String(
							decoder.decodeBuffer(resultadoNotificacion));
					
//					byte[] textoafirmarPreparado = (W83ABase64.encode(textoafirmar.getBytes("ISO-8859-1"))).getBytes("ISO-8859-1");
//					String textobueno = new String(textoafirmarPreparado);//NOPMD
					
					
					//LLAMADA A WS para obtener la firma
					W83aNSHFFacadeWS NSHFFacade = new W83aNSHFFacadeWS();
					firma=NSHFFacade.createAdESSignature(infoNotificacion.getSessionTokenXLNET(), certificateId, ejgvNotificacionB64preparado);
					
					//firma= W83AEjGvDocumento.obtenerFirmasimple(infoNotificacion.getSessionTokenXLNET(), certificateId, textobueno);
					byte[] firmaByte = firma.getBytes("ISO-8859-1");
					W83aClsTrazas.trazaDebug(null,"Resultado generar firmar---->" +firma);
//*****************************************FIN FIRMAR NOTIFICACION***********************************************************************//	
					
					
//*****************************************INICIO PUBLICAR NOTIFICACION******************************************************************//						
					if("".equals(firma)){
						W83aClsTrazas.trazaDebug(null,"No hay firma notificacion ERROR");
						//No hay firma error
						error=true;
					}else{
						//Publicamos la notificación
						String idNotificacion=W83AEjGvDocumento.publicarNotificacion(infoNotificacion.getSessionTokenXLNET(),resultadoNotificacion,new String(firmaByte));//NOPMD
						W83aClsTrazas.trazaDebug(null,"idNotificacion:" +idNotificacion);
						if (idNotificacion==null || "".equals(idNotificacion)){
							W83aClsTrazas.trazaDebug(null,"No se ha publicado la notificacion ERROR");
							error=true;
						}
					}
				//}
        	}
        	
//*****************************************FIN PUBLICAR NOTIFICACION******************************************************************//	        	
        	if(error){
        		W83aClsTrazas.trazaDebug(null, "HA HABIDO ALGÚN ERROR EN LA NOTIFICACIÓN");
            	//guardar en la base de datos.
        		W83aClsTrazas.trazaDebug(null,"guardar en la base de datos"+((W83AUsuarioBean) listaSindicatos.get(i)).getNombreUsuario()+""+i);
            	
            	int result2 = W83ANotificacionesDAO.W83AInsertarNotificaciones(infoNotificacion,direccionEnvio,((W83AUsuarioBean) listaSindicatos.get(i)).getOrganizacion());
            	if (result2==0){
            		W83aClsTrazas.trazaDebug(null,"error al insertar la notificacion");
            	}
            }
        	
        	W83aClsTrazas.trazaDebug(null," ---- FINALIZA EL THREAD ----");
        }

        
    } catch( InterruptedException e ) {
        ;
    } catch (Exception e1){
        ;
    }

    // Ahora imprimimos el nombre
    }
}
